package carte.population;

import java.awt.Color;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import carte.Cellule;
import carte.element.Mana;
import carte.element.Water;
import carte.terrain.Forest;
import carte.terrain.Mountain;

public class Vachmouth extends Individual {

	private static final String typeName = "Vachmouth";
	private static int populationCount = 0;
	// lorsque l'utilisateur (god) dechaine cet element, il le fait sur un range
	// de CLICK_RANGE avec une quantite QUANTITY_GOD avec une proba de RATIO_GOD
	public final static int RANGE_GOD = 10;
	public final static float RATIO_GOD = 0.2f;

	// points de survie
	private int faim;
	private int age;
	// points de bagarre
	private int force;
	private int poids;
	private int cornes;

	Random r;

	private enum Sexe {
		F, M
	};

	private Sexe sexe;
	private Vachmouth myChild;

	public Vachmouth() {
		super();
		populationCount++;
		r = new Random();
		faim = 0;
		age = 0;
		force = r.nextInt(10);
		poids = r.nextInt(10);
		cornes = r.nextInt(10);
		if (r.nextBoolean()) {
			sexe = Sexe.F;
			texture = Color.RED;
		} else {
			sexe = Sexe.M;
			texture = Color.WHITE;
		}
	}

	public Vachmouth(Vachmouth mere, Vachmouth pere) {
		super();
		r = new Random();
		populationCount++;
		faim = 0;
		age = 0;
		force = r.nextBoolean() ? pere.force : mere.force;
		poids = r.nextBoolean() ? pere.poids / 4 : mere.poids / 4;
		cornes = r.nextBoolean() ? pere.cornes : mere.cornes;
		if (r.nextBoolean()) {
			sexe = Sexe.F;
			texture = Color.RED;
		} else {
			sexe = Sexe.M;
			texture = Color.WHITE;
		}
		// probabilite de mourir a la mise bas
		if (r.nextDouble() < 0.5) {
			mere.kill();
			System.out.println("morte a la mise bas");
		}

		System.out.println("né " + this + "(de " + pere + " et " + mere + ")");
	}

	public static String getTypeName() {
		return typeName;
	}

	@Override
	public void evolve(ArrayList<Cellule> oldEnv, ArrayList<Cellule> newEnv) {

		int up = -1;
		age++;
		if (age > 1000) {
			kill();
			System.out.println("mort de vieillesse");
			return;
		}
		if (oldEnv.get(0).getLand() instanceof Forest) {
			faim--;
			poids++;
		} else {
			faim++;
		}
		if (faim > 40) {
			kill();
			System.out.println("mort de faim");
			return;
		}

		if (faim > 10) {
			if (oldEnv.get(0).getFluid() instanceof Water) {
				// monter pour fuir l'eau
				up = 0;
				for (int i = 1; i < oldEnv.size(); i++) {
					if (oldEnv.get(up).getAltitude() < oldEnv.get(i)
							.getAltitude()) {
						up = i;
					}
				}
				if (up > 0) {
					newEnv.get(0).removeAnimal(this);
					newEnv.get(up).addAnimal(this);
					return;
				}
			} else if (oldEnv.get(0).getLand() instanceof Mountain) {
				// descendre pour fuir la montagne
				up = 0;
				for (int i = 1; i < oldEnv.size(); i++) {
					if (oldEnv.get(up).getAltitude() > oldEnv.get(i)
							.getAltitude()) {
						up = i;
					}
				}
				if (up > 0) {
					newEnv.get(0).removeAnimal(this);
					newEnv.get(up).addAnimal(this);
					return;
				}
			}
		}

		if (oldEnv.get(0).getFluid() instanceof Water) {
			// monter pour fuir l'eau
			up = 0;
			for (int i = 1; i < oldEnv.size(); i++) {
				if (oldEnv.get(up).getAltitude() < oldEnv.get(i).getAltitude()) {
					up = i;
				}
			}
			if (up > 0) {
				newEnv.get(0).removeAnimal(this);
				newEnv.get(up).addAnimal(this);
				return;
			}
		}

		if (oldEnv.get(0).getFluid() instanceof Mana) {
			// les femelles changent de sexe
			if (r.nextDouble() < 0.7) {
				if (sexe == Sexe.F) {
					sexe = Sexe.M;
					texture = Color.WHITE;
				} else {
					sexe = Sexe.F;
					texture = Color.RED;
				}
			}
		}

		up = r.nextInt(oldEnv.size());
		newEnv.get(0).removeAnimal(this);
		newEnv.get(up).addAnimal(this);

	}

	@Override
	public Interaction interagir(List<Individual> colloc) {
		if (!isAlive())
			return Interaction.NAUGHT;

		Interaction inter = Interaction.NAUGHT;
		for (int i = 0; i < colloc.size(); i++) {
			if (colloc.get(i) != null) {
				inter = colloc.get(i).battle(this);
				if (inter == Interaction.I_DIE) {
					this.kill();
					System.out.println(this + " > " + colloc.get(i));
					return Interaction.I_DIE;
				}
				if (inter == Interaction.OTHER_DIES) {
					System.out.println(this + " < " + colloc.get(i));
					colloc.get(i).kill();
					return Interaction.OTHER_DIES;
				} else if (inter == Interaction.CHILD) {
					return Interaction.CHILD;
				}
			}
		}
		return Interaction.NAUGHT;
	}

	@Override
	public Interaction battle(Vachmouth i) {
		if (age < 10 || i.age < 10)
			return Interaction.NAUGHT;
		if (sexe != i.sexe) {
			if (i.myChild == null && this.myChild == null && age > 20
					&& i.age > 20) {
				if (sexe == Sexe.F)
					myChild = new Vachmouth(this, i);
				else
					myChild = new Vachmouth(i, this);
				i.myChild = myChild;
				return Interaction.CHILD;
			}
		} else if (i.sexe == Sexe.M) {
			if (computeBattleStrength() >= i.computeBattleStrength()) {
				force++;
				return Interaction.OTHER_DIES;
			}
			return Interaction.I_DIE;
		}
		// deux filles...
		return Interaction.NAUGHT;
	}

	/** diverses donnees multipliees par un nombre aleatoire entre 0.5 et 1 */
	private double computeBattleStrength() {
		return ((force + poids) - faim + cornes) * (r.nextDouble() / 2 + 0.5);
	}

	@Override
	public Individual getChild() {
		Vachmouth v = myChild;
		myChild = null;
		return v;
	}

	@Override
	public void kill() {
		super.kill();
		populationCount--;
	}

	@Override
	public String toString() {
		return "F:" + force + "-P:" + poids + "-C:" + cornes + "-S:" + sexe;
	}

	public static int getPopulationCount() {
		return populationCount;
	}
}
